

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8">
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <title>pytorch_tabnet.multiclass_utils &mdash; pytorch_tabnet  documentation</title>
  

  
  <link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/graphviz.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/./default.css" type="text/css" />

  
  
  
  

  
  <!--[if lt IE 9]>
    <script src="../../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
        <script src="../../_static/jquery.js"></script>
        <script src="../../_static/underscore.js"></script>
        <script src="../../_static/doctools.js"></script>
        <script src="../../_static/language_data.js"></script>
    
    <script type="text/javascript" src="../../_static/js/theme.js"></script>

    
    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" /> 
</head>

<body class="wy-body-for-nav">

   
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >
          

          
            <a href="../../index.html" class="icon icon-home" alt="Documentation Home"> pytorch_tabnet
          

          
          </a>

          
            
            
          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <p><span class="caption-text">Contents:</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/README.html">README</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/README.html#tabnet-attentive-interpretable-tabular-learning">TabNet : Attentive Interpretable Tabular Learning</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/README.html#installation">Installation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/README.html#what-is-new">What is new ?</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/README.html#contributing">Contributing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/README.html#what-problems-does-pytorch-tabnet-handle">What problems does pytorch-tabnet handle?</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/README.html#how-to-use-it">How to use it?</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/README.html#semi-supervised-pre-training">Semi-supervised pre-training</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/README.html#data-augmentation-on-the-fly">Data augmentation on the fly</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/README.html#easy-saving-and-loading">Easy saving and loading</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/README.html#useful-links">Useful links</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../generated_docs/pytorch_tabnet.html">pytorch_tabnet package</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../index.html">pytorch_tabnet</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="../../index.html" class="icon icon-home"></a> &raquo;</li>
        
          <li><a href="../index.html">Module code</a> &raquo;</li>
        
      <li>pytorch_tabnet.multiclass_utils</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
      </li>
    
  </ul>

  
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
  <h1>Source code for pytorch_tabnet.multiclass_utils</h1><div class="highlight"><pre>
<span></span><span class="c1"># Author: Arnaud Joly, Joel Nothman, Hamzeh Alsalhi</span>
<span class="c1">#</span>
<span class="c1"># License: BSD 3 clause</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Multi-class / multi-label utility function</span>
<span class="sd">==========================================</span>

<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">collections.abc</span> <span class="kn">import</span> <span class="n">Sequence</span>
<span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">chain</span>

<span class="kn">from</span> <span class="nn">scipy.sparse</span> <span class="kn">import</span> <span class="n">issparse</span>
<span class="kn">from</span> <span class="nn">scipy.sparse.base</span> <span class="kn">import</span> <span class="n">spmatrix</span>
<span class="kn">from</span> <span class="nn">scipy.sparse</span> <span class="kn">import</span> <span class="n">dok_matrix</span>
<span class="kn">from</span> <span class="nn">scipy.sparse</span> <span class="kn">import</span> <span class="n">lil_matrix</span>
<span class="kn">import</span> <span class="nn">scipy.sparse</span> <span class="k">as</span> <span class="nn">sp</span>

<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>


<span class="k">def</span> <span class="nf">_assert_all_finite</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">allow_nan</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Like assert_all_finite, but only for ndarray.&quot;&quot;&quot;</span>

    <span class="n">X</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asanyarray</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
    <span class="c1"># First try an O(n) time, O(1) space solution for the common case that</span>
    <span class="c1"># everything is finite; fall back to O(n) space np.isfinite to prevent</span>
    <span class="c1"># false positives from overflow in sum method. The sum is also calculated</span>
    <span class="c1"># safely to reduce dtype induced overflows.</span>
    <span class="n">is_float</span> <span class="o">=</span> <span class="n">X</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="s2">&quot;fc&quot;</span>
    <span class="k">if</span> <span class="n">is_float</span> <span class="ow">and</span> <span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">isfinite</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">X</span><span class="p">))):</span>
        <span class="k">pass</span>
    <span class="k">elif</span> <span class="n">is_float</span><span class="p">:</span>
        <span class="n">msg_err</span> <span class="o">=</span> <span class="s2">&quot;Input contains </span><span class="si">{}</span><span class="s2"> or a value too large for </span><span class="si">{!r}</span><span class="s2">.&quot;</span>
        <span class="k">if</span> <span class="p">(</span>
            <span class="n">allow_nan</span>
            <span class="ow">and</span> <span class="n">np</span><span class="o">.</span><span class="n">isinf</span><span class="p">(</span><span class="n">X</span><span class="p">)</span><span class="o">.</span><span class="n">any</span><span class="p">()</span>
            <span class="ow">or</span> <span class="ow">not</span> <span class="n">allow_nan</span>
            <span class="ow">and</span> <span class="ow">not</span> <span class="n">np</span><span class="o">.</span><span class="n">isfinite</span><span class="p">(</span><span class="n">X</span><span class="p">)</span><span class="o">.</span><span class="n">all</span><span class="p">()</span>
        <span class="p">):</span>
            <span class="n">type_err</span> <span class="o">=</span> <span class="s2">&quot;infinity&quot;</span> <span class="k">if</span> <span class="n">allow_nan</span> <span class="k">else</span> <span class="s2">&quot;NaN, infinity&quot;</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="n">msg_err</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">type_err</span><span class="p">,</span> <span class="n">X</span><span class="o">.</span><span class="n">dtype</span><span class="p">))</span>
    <span class="c1"># for object dtype data, we only check for NaNs (GH-13254)</span>
    <span class="k">elif</span> <span class="n">X</span><span class="o">.</span><span class="n">dtype</span> <span class="o">==</span> <span class="n">np</span><span class="o">.</span><span class="n">dtype</span><span class="p">(</span><span class="s2">&quot;object&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">allow_nan</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">np</span><span class="o">.</span><span class="n">isnan</span><span class="p">(</span><span class="n">X</span><span class="p">)</span><span class="o">.</span><span class="n">any</span><span class="p">():</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Input contains NaN&quot;</span><span class="p">)</span>


<div class="viewcode-block" id="assert_all_finite"><a class="viewcode-back" href="../../generated_docs/pytorch_tabnet.html#pytorch_tabnet.multiclass_utils.assert_all_finite">[docs]</a><span class="k">def</span> <span class="nf">assert_all_finite</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">allow_nan</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Throw a ValueError if X contains NaN or infinity.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    X : array or sparse matrix</span>
<span class="sd">    allow_nan : bool</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">_assert_all_finite</span><span class="p">(</span><span class="n">X</span><span class="o">.</span><span class="n">data</span> <span class="k">if</span> <span class="n">sp</span><span class="o">.</span><span class="n">issparse</span><span class="p">(</span><span class="n">X</span><span class="p">)</span> <span class="k">else</span> <span class="n">X</span><span class="p">,</span> <span class="n">allow_nan</span><span class="p">)</span></div>


<span class="k">def</span> <span class="nf">_unique_multiclass</span><span class="p">(</span><span class="n">y</span><span class="p">):</span>
    <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="s2">&quot;__array__&quot;</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">unique</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">y</span><span class="p">))</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="nb">set</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">_unique_indicator</span><span class="p">(</span><span class="n">y</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Not implemented</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">raise</span> <span class="ne">IndexError</span><span class="p">(</span>
        <span class="sa">f</span><span class="s2">&quot;&quot;&quot;Given labels are of size </span><span class="si">{</span><span class="n">y</span><span class="o">.</span><span class="n">shape</span><span class="si">}</span><span class="s2"> while they should be (n_samples,) </span><span class="se">\n</span><span class="s2">&quot;&quot;&quot;</span>
        <span class="o">+</span> <span class="s2">&quot;&quot;&quot;If attempting multilabel classification, try using TabNetMultiTaskClassification &quot;&quot;&quot;</span>
        <span class="o">+</span> <span class="s2">&quot;&quot;&quot;or TabNetRegressor&quot;&quot;&quot;</span>
    <span class="p">)</span>


<span class="n">_FN_UNIQUE_LABELS</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s2">&quot;binary&quot;</span><span class="p">:</span> <span class="n">_unique_multiclass</span><span class="p">,</span>
    <span class="s2">&quot;multiclass&quot;</span><span class="p">:</span> <span class="n">_unique_multiclass</span><span class="p">,</span>
    <span class="s2">&quot;multilabel-indicator&quot;</span><span class="p">:</span> <span class="n">_unique_indicator</span><span class="p">,</span>
<span class="p">}</span>


<div class="viewcode-block" id="unique_labels"><a class="viewcode-back" href="../../generated_docs/pytorch_tabnet.html#pytorch_tabnet.multiclass_utils.unique_labels">[docs]</a><span class="k">def</span> <span class="nf">unique_labels</span><span class="p">(</span><span class="o">*</span><span class="n">ys</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Extract an ordered array of unique labels</span>

<span class="sd">    We don&#39;t allow:</span>
<span class="sd">        - mix of multilabel and multiclass (single label) targets</span>
<span class="sd">        - mix of label indicator matrix and anything else,</span>
<span class="sd">          because there are no explicit labels)</span>
<span class="sd">        - mix of label indicator matrices of different sizes</span>
<span class="sd">        - mix of string and integer labels</span>

<span class="sd">    At the moment, we also don&#39;t allow &quot;multiclass-multioutput&quot; input type.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    *ys : array-likes</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    out : numpy array of shape [n_unique_labels]</span>
<span class="sd">        An ordered array of unique labels.</span>

<span class="sd">    Examples</span>
<span class="sd">    --------</span>
<span class="sd">    &gt;&gt;&gt; from sklearn.utils.multiclass import unique_labels</span>
<span class="sd">    &gt;&gt;&gt; unique_labels([3, 5, 5, 5, 7, 7])</span>
<span class="sd">    array([3, 5, 7])</span>
<span class="sd">    &gt;&gt;&gt; unique_labels([1, 2, 3, 4], [2, 2, 3, 4])</span>
<span class="sd">    array([1, 2, 3, 4])</span>
<span class="sd">    &gt;&gt;&gt; unique_labels([1, 2, 10], [5, 11])</span>
<span class="sd">    array([ 1,  2,  5, 10, 11])</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">ys</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;No argument has been passed.&quot;</span><span class="p">)</span>
    <span class="c1"># Check that we don&#39;t mix label format</span>

    <span class="n">ys_types</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">type_of_target</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">ys</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">ys_types</span> <span class="o">==</span> <span class="p">{</span><span class="s2">&quot;binary&quot;</span><span class="p">,</span> <span class="s2">&quot;multiclass&quot;</span><span class="p">}:</span>
        <span class="n">ys_types</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;multiclass&quot;</span><span class="p">}</span>

    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">ys_types</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Mix type of y not allowed, got types </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">ys_types</span><span class="p">)</span>

    <span class="n">label_type</span> <span class="o">=</span> <span class="n">ys_types</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>

    <span class="c1"># Get the unique set of labels</span>
    <span class="n">_unique_labels</span> <span class="o">=</span> <span class="n">_FN_UNIQUE_LABELS</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">label_type</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">_unique_labels</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Unknown label type: </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="nb">repr</span><span class="p">(</span><span class="n">ys</span><span class="p">))</span>

    <span class="n">ys_labels</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">chain</span><span class="o">.</span><span class="n">from_iterable</span><span class="p">(</span><span class="n">_unique_labels</span><span class="p">(</span><span class="n">y</span><span class="p">)</span> <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">ys</span><span class="p">))</span>

    <span class="c1"># Check that we don&#39;t mix string type with number type</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="nb">isinstance</span><span class="p">(</span><span class="n">label</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="k">for</span> <span class="n">label</span> <span class="ow">in</span> <span class="n">ys_labels</span><span class="p">))</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Mix of label input types (string and number)&quot;</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">ys_labels</span><span class="p">))</span></div>


<span class="k">def</span> <span class="nf">_is_integral_float</span><span class="p">(</span><span class="n">y</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">y</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="s2">&quot;f&quot;</span> <span class="ow">and</span> <span class="n">np</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="n">y</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span> <span class="o">==</span> <span class="n">y</span><span class="p">)</span>


<div class="viewcode-block" id="is_multilabel"><a class="viewcode-back" href="../../generated_docs/pytorch_tabnet.html#pytorch_tabnet.multiclass_utils.is_multilabel">[docs]</a><span class="k">def</span> <span class="nf">is_multilabel</span><span class="p">(</span><span class="n">y</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Check if ``y`` is in a multilabel format.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    y : numpy array of shape [n_samples]</span>
<span class="sd">        Target values.</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    out : bool</span>
<span class="sd">        Return ``True``, if ``y`` is in a multilabel format, else ```False``.</span>

<span class="sd">    Examples</span>
<span class="sd">    --------</span>
<span class="sd">    &gt;&gt;&gt; import numpy as np</span>
<span class="sd">    &gt;&gt;&gt; from sklearn.utils.multiclass import is_multilabel</span>
<span class="sd">    &gt;&gt;&gt; is_multilabel([0, 1, 0, 1])</span>
<span class="sd">    False</span>
<span class="sd">    &gt;&gt;&gt; is_multilabel([[1], [0, 2], []])</span>
<span class="sd">    False</span>
<span class="sd">    &gt;&gt;&gt; is_multilabel(np.array([[1, 0], [0, 0]]))</span>
<span class="sd">    True</span>
<span class="sd">    &gt;&gt;&gt; is_multilabel(np.array([[1], [0], [0]]))</span>
<span class="sd">    False</span>
<span class="sd">    &gt;&gt;&gt; is_multilabel(np.array([[1, 0, 0]]))</span>
<span class="sd">    True</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="s2">&quot;__array__&quot;</span><span class="p">):</span>
        <span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="nb">hasattr</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="s2">&quot;shape&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">y</span><span class="o">.</span><span class="n">ndim</span> <span class="o">==</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">y</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">):</span>
        <span class="k">return</span> <span class="kc">False</span>

    <span class="k">if</span> <span class="n">issparse</span><span class="p">(</span><span class="n">y</span><span class="p">):</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="p">(</span><span class="n">dok_matrix</span><span class="p">,</span> <span class="n">lil_matrix</span><span class="p">)):</span>
            <span class="n">y</span> <span class="o">=</span> <span class="n">y</span><span class="o">.</span><span class="n">tocsr</span><span class="p">()</span>
        <span class="k">return</span> <span class="p">(</span>
            <span class="nb">len</span><span class="p">(</span><span class="n">y</span><span class="o">.</span><span class="n">data</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span>
            <span class="ow">or</span> <span class="n">np</span><span class="o">.</span><span class="n">unique</span><span class="p">(</span><span class="n">y</span><span class="o">.</span><span class="n">data</span><span class="p">)</span><span class="o">.</span><span class="n">size</span> <span class="o">==</span> <span class="mi">1</span>
            <span class="ow">and</span> <span class="p">(</span>
                <span class="n">y</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="s2">&quot;biu&quot;</span>
                <span class="ow">or</span> <span class="n">_is_integral_float</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">unique</span><span class="p">(</span><span class="n">y</span><span class="o">.</span><span class="n">data</span><span class="p">))</span>  <span class="c1"># bool, int, uint</span>
            <span class="p">)</span>
        <span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">unique</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>

        <span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="n">labels</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">3</span> <span class="ow">and</span> <span class="p">(</span>
            <span class="n">y</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">kind</span> <span class="ow">in</span> <span class="s2">&quot;biu&quot;</span> <span class="ow">or</span> <span class="n">_is_integral_float</span><span class="p">(</span><span class="n">labels</span><span class="p">)</span>  <span class="c1"># bool, int, uint</span>
        <span class="p">)</span></div>


<div class="viewcode-block" id="check_classification_targets"><a class="viewcode-back" href="../../generated_docs/pytorch_tabnet.html#pytorch_tabnet.multiclass_utils.check_classification_targets">[docs]</a><span class="k">def</span> <span class="nf">check_classification_targets</span><span class="p">(</span><span class="n">y</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Ensure that target y is of a non-regression type.</span>

<span class="sd">    Only the following target types (as defined in type_of_target) are allowed:</span>
<span class="sd">        &#39;binary&#39;, &#39;multiclass&#39;, &#39;multiclass-multioutput&#39;,</span>
<span class="sd">        &#39;multilabel-indicator&#39;, &#39;multilabel-sequences&#39;</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    y : array-like</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">y_type</span> <span class="o">=</span> <span class="n">type_of_target</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">y_type</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span>
        <span class="s2">&quot;binary&quot;</span><span class="p">,</span>
        <span class="s2">&quot;multiclass&quot;</span><span class="p">,</span>
        <span class="s2">&quot;multiclass-multioutput&quot;</span><span class="p">,</span>
        <span class="s2">&quot;multilabel-indicator&quot;</span><span class="p">,</span>
        <span class="s2">&quot;multilabel-sequences&quot;</span><span class="p">,</span>
    <span class="p">]:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Unknown label type: </span><span class="si">%r</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">y_type</span><span class="p">)</span></div>


<div class="viewcode-block" id="type_of_target"><a class="viewcode-back" href="../../generated_docs/pytorch_tabnet.html#pytorch_tabnet.multiclass_utils.type_of_target">[docs]</a><span class="k">def</span> <span class="nf">type_of_target</span><span class="p">(</span><span class="n">y</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Determine the type of data indicated by the target.</span>

<span class="sd">    Note that this type is the most specific type that can be inferred.</span>
<span class="sd">    For example:</span>

<span class="sd">        * ``binary`` is more specific but compatible with ``multiclass``.</span>
<span class="sd">        * ``multiclass`` of integers is more specific but compatible with</span>
<span class="sd">          ``continuous``.</span>
<span class="sd">        * ``multilabel-indicator`` is more specific but compatible with</span>
<span class="sd">          ``multiclass-multioutput``.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    y : array-like</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    target_type : string</span>
<span class="sd">        One of:</span>

<span class="sd">        * &#39;continuous&#39;: `y` is an array-like of floats that are not all</span>
<span class="sd">          integers, and is 1d or a column vector.</span>
<span class="sd">        * &#39;continuous-multioutput&#39;: `y` is a 2d array of floats that are</span>
<span class="sd">          not all integers, and both dimensions are of size &gt; 1.</span>
<span class="sd">        * &#39;binary&#39;: `y` contains &lt;= 2 discrete values and is 1d or a column</span>
<span class="sd">          vector.</span>
<span class="sd">        * &#39;multiclass&#39;: `y` contains more than two discrete values, is not a</span>
<span class="sd">          sequence of sequences, and is 1d or a column vector.</span>
<span class="sd">        * &#39;multiclass-multioutput&#39;: `y` is a 2d array that contains more</span>
<span class="sd">          than two discrete values, is not a sequence of sequences, and both</span>
<span class="sd">          dimensions are of size &gt; 1.</span>
<span class="sd">        * &#39;multilabel-indicator&#39;: `y` is a label indicator matrix, an array</span>
<span class="sd">          of two dimensions with at least two columns, and at most 2 unique</span>
<span class="sd">          values.</span>
<span class="sd">        * &#39;unknown&#39;: `y` is array-like but none of the above, such as a 3d</span>
<span class="sd">          array, sequence of sequences, or an array of non-sequence objects.</span>

<span class="sd">    Examples</span>
<span class="sd">    --------</span>
<span class="sd">    &gt;&gt;&gt; import numpy as np</span>
<span class="sd">    &gt;&gt;&gt; type_of_target([0.1, 0.6])</span>
<span class="sd">    &#39;continuous&#39;</span>
<span class="sd">    &gt;&gt;&gt; type_of_target([1, -1, -1, 1])</span>
<span class="sd">    &#39;binary&#39;</span>
<span class="sd">    &gt;&gt;&gt; type_of_target([&#39;a&#39;, &#39;b&#39;, &#39;a&#39;])</span>
<span class="sd">    &#39;binary&#39;</span>
<span class="sd">    &gt;&gt;&gt; type_of_target([1.0, 2.0])</span>
<span class="sd">    &#39;binary&#39;</span>
<span class="sd">    &gt;&gt;&gt; type_of_target([1, 0, 2])</span>
<span class="sd">    &#39;multiclass&#39;</span>
<span class="sd">    &gt;&gt;&gt; type_of_target([1.0, 0.0, 3.0])</span>
<span class="sd">    &#39;multiclass&#39;</span>
<span class="sd">    &gt;&gt;&gt; type_of_target([&#39;a&#39;, &#39;b&#39;, &#39;c&#39;])</span>
<span class="sd">    &#39;multiclass&#39;</span>
<span class="sd">    &gt;&gt;&gt; type_of_target(np.array([[1, 2], [3, 1]]))</span>
<span class="sd">    &#39;multiclass-multioutput&#39;</span>
<span class="sd">    &gt;&gt;&gt; type_of_target([[1, 2]])</span>
<span class="sd">    &#39;multiclass-multioutput&#39;</span>
<span class="sd">    &gt;&gt;&gt; type_of_target(np.array([[1.5, 2.0], [3.0, 1.6]]))</span>
<span class="sd">    &#39;continuous-multioutput&#39;</span>
<span class="sd">    &gt;&gt;&gt; type_of_target(np.array([[0, 1], [1, 1]]))</span>
<span class="sd">    &#39;multilabel-indicator&#39;</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">valid</span> <span class="o">=</span> <span class="p">(</span>
        <span class="nb">isinstance</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="p">(</span><span class="n">Sequence</span><span class="p">,</span> <span class="n">spmatrix</span><span class="p">))</span> <span class="ow">or</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="s2">&quot;__array__&quot;</span><span class="p">)</span>
    <span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span>

    <span class="k">if</span> <span class="ow">not</span> <span class="n">valid</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
            <span class="s2">&quot;Expected array-like (array or non-string sequence), &quot;</span> <span class="s2">&quot;got </span><span class="si">%r</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">y</span>
        <span class="p">)</span>

    <span class="n">sparseseries</span> <span class="o">=</span> <span class="n">y</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;SparseSeries&quot;</span>
    <span class="k">if</span> <span class="n">sparseseries</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;y cannot be class &#39;SparseSeries&#39;.&quot;</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">is_multilabel</span><span class="p">(</span><span class="n">y</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;multilabel-indicator&quot;</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
    <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
        <span class="c1"># Known to fail in numpy 1.3 for array of arrays</span>
        <span class="k">return</span> <span class="s2">&quot;unknown&quot;</span>

    <span class="c1"># The old sequence of sequences format</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">if</span> <span class="p">(</span>
            <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="s2">&quot;__array__&quot;</span><span class="p">)</span>
            <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">Sequence</span><span class="p">)</span>
            <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">str</span><span class="p">)</span>
        <span class="p">):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                <span class="s2">&quot;You appear to be using a legacy multi-label data&quot;</span>
                <span class="s2">&quot; representation. Sequence of sequences are no&quot;</span>
                <span class="s2">&quot; longer supported; use a binary array or sparse&quot;</span>
                <span class="s2">&quot; matrix instead - the MultiLabelBinarizer&quot;</span>
                <span class="s2">&quot; transformer can convert to this format.&quot;</span>
            <span class="p">)</span>
    <span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
        <span class="k">pass</span>

    <span class="c1"># Invalid inputs</span>
    <span class="k">if</span> <span class="n">y</span><span class="o">.</span><span class="n">ndim</span> <span class="o">&gt;</span> <span class="mi">2</span> <span class="ow">or</span> <span class="p">(</span><span class="n">y</span><span class="o">.</span><span class="n">dtype</span> <span class="o">==</span> <span class="nb">object</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">y</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">y</span><span class="o">.</span><span class="n">flat</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nb">str</span><span class="p">)):</span>
        <span class="k">return</span> <span class="s2">&quot;unknown&quot;</span>  <span class="c1"># [[[1, 2]]] or [obj_1] and not [&quot;label_1&quot;]</span>

    <span class="k">if</span> <span class="n">y</span><span class="o">.</span><span class="n">ndim</span> <span class="o">==</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">y</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="s2">&quot;unknown&quot;</span>  <span class="c1"># [[]]</span>

    <span class="k">if</span> <span class="n">y</span><span class="o">.</span><span class="n">ndim</span> <span class="o">==</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">y</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
        <span class="n">suffix</span> <span class="o">=</span> <span class="s2">&quot;-multioutput&quot;</span>  <span class="c1"># [[1, 2], [1, 2]]</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">suffix</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>  <span class="c1"># [1, 2, 3] or [[1], [2], [3]]</span>

    <span class="c1"># check float and contains non-integer float values</span>
    <span class="k">if</span> <span class="n">y</span><span class="o">.</span><span class="n">dtype</span><span class="o">.</span><span class="n">kind</span> <span class="o">==</span> <span class="s2">&quot;f&quot;</span> <span class="ow">and</span> <span class="n">np</span><span class="o">.</span><span class="n">any</span><span class="p">(</span><span class="n">y</span> <span class="o">!=</span> <span class="n">y</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="nb">int</span><span class="p">)):</span>
        <span class="c1"># [.1, .2, 3] or [[.1, .2, 3]] or [[1., .2]] and not [1., 2., 3.]</span>
        <span class="n">_assert_all_finite</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
        <span class="k">return</span> <span class="s2">&quot;continuous&quot;</span> <span class="o">+</span> <span class="n">suffix</span>

    <span class="k">if</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">unique</span><span class="p">(</span><span class="n">y</span><span class="p">))</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="n">y</span><span class="o">.</span><span class="n">ndim</span> <span class="o">&gt;=</span> <span class="mi">2</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">):</span>
        <span class="k">return</span> <span class="s2">&quot;multiclass&quot;</span> <span class="o">+</span> <span class="n">suffix</span>  <span class="c1"># [1, 2, 3] or [[1., 2., 3]] or [[1, 2]]</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="s2">&quot;binary&quot;</span>  <span class="c1"># [1, 2] or [[&quot;a&quot;], [&quot;b&quot;]]</span></div>


<div class="viewcode-block" id="check_unique_type"><a class="viewcode-back" href="../../generated_docs/pytorch_tabnet.html#pytorch_tabnet.multiclass_utils.check_unique_type">[docs]</a><span class="k">def</span> <span class="nf">check_unique_type</span><span class="p">(</span><span class="n">y</span><span class="p">):</span>
    <span class="n">target_types</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">Series</span><span class="p">(</span><span class="n">y</span><span class="p">)</span><span class="o">.</span><span class="n">map</span><span class="p">(</span><span class="nb">type</span><span class="p">)</span><span class="o">.</span><span class="n">unique</span><span class="p">()</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">target_types</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span>
            <span class="sa">f</span><span class="s2">&quot;Values on the target must have the same type. Target has types </span><span class="si">{</span><span class="n">target_types</span><span class="si">}</span><span class="s2">&quot;</span>
        <span class="p">)</span></div>


<div class="viewcode-block" id="infer_output_dim"><a class="viewcode-back" href="../../generated_docs/pytorch_tabnet.html#pytorch_tabnet.multiclass_utils.infer_output_dim">[docs]</a><span class="k">def</span> <span class="nf">infer_output_dim</span><span class="p">(</span><span class="n">y_train</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Infer output_dim from targets</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    y_train : np.array</span>
<span class="sd">        Training targets</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    output_dim : int</span>
<span class="sd">        Number of classes for output</span>
<span class="sd">    train_labels : list</span>
<span class="sd">        Sorted list of initial classes</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">check_unique_type</span><span class="p">(</span><span class="n">y_train</span><span class="p">)</span>
    <span class="n">train_labels</span> <span class="o">=</span> <span class="n">unique_labels</span><span class="p">(</span><span class="n">y_train</span><span class="p">)</span>
    <span class="n">output_dim</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">train_labels</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">output_dim</span><span class="p">,</span> <span class="n">train_labels</span></div>


<div class="viewcode-block" id="check_output_dim"><a class="viewcode-back" href="../../generated_docs/pytorch_tabnet.html#pytorch_tabnet.multiclass_utils.check_output_dim">[docs]</a><span class="k">def</span> <span class="nf">check_output_dim</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">y</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
        <span class="n">check_unique_type</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
        <span class="n">valid_labels</span> <span class="o">=</span> <span class="n">unique_labels</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">set</span><span class="p">(</span><span class="n">valid_labels</span><span class="p">)</span><span class="o">.</span><span class="n">issubset</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">labels</span><span class="p">)):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                <span class="sa">f</span><span class="s2">&quot;&quot;&quot;Valid set -- </span><span class="si">{</span><span class="nb">set</span><span class="p">(</span><span class="n">valid_labels</span><span class="p">)</span><span class="si">}</span><span class="s2"> --</span>
<span class="s2">                             contains unkown targets from training --</span>
<span class="s2">                             </span><span class="si">{</span><span class="nb">set</span><span class="p">(</span><span class="n">labels</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;&quot;&quot;</span>
            <span class="p">)</span>
    <span class="k">return</span></div>


<div class="viewcode-block" id="infer_multitask_output"><a class="viewcode-back" href="../../generated_docs/pytorch_tabnet.html#pytorch_tabnet.multiclass_utils.infer_multitask_output">[docs]</a><span class="k">def</span> <span class="nf">infer_multitask_output</span><span class="p">(</span><span class="n">y_train</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Infer output_dim from targets</span>
<span class="sd">    This is for multiple tasks.</span>

<span class="sd">    Parameters</span>
<span class="sd">    ----------</span>
<span class="sd">    y_train : np.ndarray</span>
<span class="sd">        Training targets</span>

<span class="sd">    Returns</span>
<span class="sd">    -------</span>
<span class="sd">    tasks_dims : list</span>
<span class="sd">        Number of classes for output</span>
<span class="sd">    tasks_labels : list</span>
<span class="sd">        List of sorted list of initial classes</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">y_train</span><span class="o">.</span><span class="n">shape</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
            <span class="s2">&quot;y_train should be of shape (n_examples, n_tasks)&quot;</span>
            <span class="o">+</span> <span class="sa">f</span><span class="s2">&quot;but got </span><span class="si">{</span><span class="n">y_train</span><span class="o">.</span><span class="n">shape</span><span class="si">}</span><span class="s2">&quot;</span>
        <span class="p">)</span>
    <span class="n">nb_tasks</span> <span class="o">=</span> <span class="n">y_train</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
    <span class="n">tasks_dims</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="n">tasks_labels</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">task_idx</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">nb_tasks</span><span class="p">):</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">output_dim</span><span class="p">,</span> <span class="n">train_labels</span> <span class="o">=</span> <span class="n">infer_output_dim</span><span class="p">(</span><span class="n">y_train</span><span class="p">[:,</span> <span class="n">task_idx</span><span class="p">])</span>
            <span class="n">tasks_dims</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">output_dim</span><span class="p">)</span>
            <span class="n">tasks_labels</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">train_labels</span><span class="p">)</span>
        <span class="k">except</span> <span class="ne">ValueError</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;&quot;&quot;Error for task </span><span class="si">{</span><span class="n">task_idx</span><span class="si">}</span><span class="s2"> : </span><span class="si">{</span><span class="n">err</span><span class="si">}</span><span class="s2">&quot;&quot;&quot;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">tasks_dims</span><span class="p">,</span> <span class="n">tasks_labels</span></div>
</pre></div>

           </div>
           
          </div>
          <footer>
  

  <hr/>

  <div role="contentinfo">
    <p>
        
        &copy; Copyright 2019, Dreamquark

    </p>
  </div>
    
    
    
    Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a
    
    <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a>
    
    provided by <a href="https://readthedocs.org">Read the Docs</a>. 

</footer>

        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>